<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Using Extensions : DataMapper ORM - User Guide</title>

<link rel="shortcut icon" type="image/png" href="../images/favicon.png" />
<link rel="stylesheet" type="text/css" media="all" href="../css/userguide.css" />
<link rel="alternate" type="application/rss+xml" title="Datamapper ORM Updates Feed" href="/rss.xml" />

<meta http-equiv="expires" content="-1" />
<meta http-equiv= 'pragma' content="no-cache" />
<meta name="robots" content="all" />

</head>

<body>

<!-- START NAVIGATION -->
<div id="nav"><div id="nav_inner"></div></div>
<div id="nav2"><a name="top">&nbsp;</a><a id="nav_toggle" href="#"><img src="../images/nav_toggle_darker.jpg" width="154" height="43" border="0" title="Toggle Table of Contents" alt="Toggle Table of Contents" /></a></div>
<div id="masthead">
<table cellpadding="0" cellspacing="0" border="0" style="width:100%">
<tr>
<td><h1>DataMapper ORM</h1></td>
<td id="breadcrumb_right"><a href="toc.html">Table of Contents Page</a></td>
</tr>
</table>
</div>
<!-- END NAVIGATION -->

<!-- START BREADCRUMB -->
<table cellpadding="0" cellspacing="0" border="0" style="width:100%">
<tr>
<td id="breadcrumb">
<a href="/">Datamapper ORM Home</a> &nbsp;&#8250;&nbsp;
<a href="../index.html">User Guide Home</a> &nbsp;&#8250;&nbsp;
Using Extensions
</td>
</tr>

</table>
<!-- END BREADCRUMB -->

<br clear="all" />


<!-- START CONTENT -->
<div id="content">


<h1>Using Extensions</h1>

<p>Not everyone needs every feature all the time.  Datamapper ORM has been designed to allow simple extensions that enable you to enhance DataMapper models.  There are two primary ways to extend DataMapper, which can be used at the same time.</p>
<ul>
	<li><a href="#Extensions">Using Shareable Extension Classes</a></li>
	<li><a href="#DataMapperExt">Extending DataMapper Directly</a></li>
</ul>

<p>The techniques differ greatly, and will be described in brief below.</p>

<h2 id="Extensions">Using Shareable Extension Classes</h2>

<p>This is the recommended way of extending a DataMapper model.  This technique allows you to add methods and custom validation rules to DataMapper models, without having to change any existing code.</p>

<p>It works by calling non-private methods on separate classes as needed.  These classes are usually stored within the <b>application</b>/<kbd>datamapper</kbd> directory.  You can change this directory by changing the DataMapper config item <var><i>'extensions_path'</i></var>.</p>

<p>An extension is automatically loaded either globally, through the DataMapper config, or on a per-class basis, through the <var><i>$extensions</i></var> array.  The order you load the methods matters, as the first extensions loaded take precedence over later ones.  (Per-class or local extensions will also override global extensions.)  You can also load an extension on-the-fly using <var><u>load_extension</u></var>.</p>

<h3>Adding a Global Extension</h3>
<pre>
<samp>// In DataMapper Config
</samp><var>$config</var><kbd>[</kbd><dfn>'extensions'</dfn><kbd>] = array(</kbd><dfn>'json'</dfn><kbd>); </kbd><samp>// Include the json extension</samp>
</pre>

<h3>Adding an Extension to the User Class Only</h3>
<pre>
<kbd>class </kbd><var>User </var><kbd>extends </kbd><var><u>DataMapper</u> </var><kbd>{

    </kbd><samp>// Include the json extension
    </samp><kbd>var </kbd><var><i>$extensions</i> </var><kbd>= array(</kbd><dfn>'json'</dfn><kbd>);

    </kbd><samp>// ...</samp>
</pre>

<h3>Loading Global Extensions Dynamically with <dfn>load_extension</dfn></h3>
<pre>
<var>$user </var><kbd>= new </kbd><var>User</var><kbd>();
</kbd><samp>// load csv, which is now available on all DataMapper objects.
</samp><var>$user</var><kbd>-&gt;</kbd><var><u>load_extension</u></var><kbd>(</kbd><dfn>'csv'</dfn><kbd>);</kbd>
</pre>

<p class="note">You can also include other files that are stored relative to the <b>application</b> directory by including the path.  For example, to include a library, you would use '<b>library/mylibary</b>'</p>

<p>Note that all three can coexist.  You can load some extensions in globally and others locally, at the same time, and still others on-the-fly.</p>

<a name="Options"></a>
<div class="highlight">
	<p>Some extensions include the ability to pass in options.</p>

<h4>Adding a Global Extension with Options</h4>
<pre>
<samp>// In DataMapper Config
</samp><var>$config</var><kbd>[</kbd><dfn>'extensions'</dfn><kbd>] = array(</kbd><dfn>'htmlform' </dfn><kbd>=&gt; array(
    </kbd><dfn>'form_template' </dfn><kbd>=&gt; </kbd><dfn>'my_form_template'
</dfn><kbd>));</kbd>
</pre>

<h4>Dynamically Loading a Single (Global) Extension with Options</h4>
<pre>
<var>$user </var><kbd>= new </kbd><var>User</var><kbd>();
</kbd><samp>// load htmlform, which is now available on all DataMapper objects.
</samp><var>$user</var><kbd>-&gt;</kbd><var><u>load_extension</u></var><kbd>(</kbd><dfn>'htmlform'</dfn><kbd>, array(</kbd><dfn>'row_template' </dfn><kbd>=&gt; </kbd><dfn>'my_row_template'</dfn><kbd>));</kbd>
</pre>

<h4>Dynamically Loading a Single (Local) Extension with Options</h4>
<p>You can also dynamically load an extension for a single class.  This allows you to provide different options for each model.</p>
<pre>
<var>$user </var><kbd>= new </kbd><var>User</var><kbd>();
</kbd><samp>// load htmlform, which is now available on all DataMapper objects.
</samp><var>$user</var><kbd>-&gt;</kbd><var><u>load_extension</u></var><kbd>(</kbd><dfn>'htmlform'</dfn><kbd>, array(</kbd><dfn>'row_template' </dfn><kbd>=&gt; </kbd><dfn>'my_row_template'</dfn><kbd>)</kbd><em class="new"><kbd>, </kbd><var><dfn>TRUE</dfn></var></em><kbd>);</kbd>
</pre>
</div>

<h3>Using the Extension</h3>
<p>The extensions work by adding methods directly to the DataMapper models.  In the above example, the <kbd>json</kbd> extension adds several methods, including:</p>
<ul>
	<li><var><s>to_json</s></var><kbd>()</kbd></li>
	<li><var><s>from_json</s></var><kbd>()</kbd></li>
</ul>
<p>These methods would be called as a normal method:</p>
<pre>
<var>$u </var><kbd>= new </kbd><var>User</var><kbd>();
</kbd><var>$u</var><kbd>-&gt;</kbd><var><u>get_by_id</u></var><kbd>(</kbd><var>$user_id</var><kbd>);
echo </kbd><var>$u</var><kbd>-&gt;</kbd><var><s>to_json</s></var><kbd>();</kbd>
</pre>

<p>You can <a href="extwrite.html">Learn more about writing your own extensions</a>, or you can view the <a href="extlist.html">list of included extensions</a>.</p>

<p>&nbsp;</p>

<h2 id="DataMapperExt">Extending DataMapper Directly</h2>

<p>Some features are not able to be added using the extensions mechanism.  This includes those that need to override built-in DataMapper methods.</p>

<p>To handle these, it is recommended that you create a class that extends DataMapper, and use that as your base class for your models.  You can call it whatever you like, but for the examples below, I named it <var>DataMapperExt</var>:</p>
<h3>application/models/datamapperext.php</h3>
<pre>
<kbd>class </kbd><var>DataMapperExt </var><kbd>extends </kbd><var><u>DataMapper</u> </var><kbd>{
    function </kbd><var><dfn>__construct</dfn></var><kbd>(</kbd><var>$id </var><kbd>= </kbd><var>NULL</var><kbd>) {
        </kbd><var><dfn>parent</dfn></var><kbd>::</kbd><var><dfn>__construct</dfn></var><kbd>(</kbd><var>$id</var><kbd>);
    }

    </kbd><samp>// Add your method(s) here, such as:

    // only get if $this wasn't already loaded
    </samp><kbd>function </kbd><var>get_once</var><kbd>()
    {
        if( ! </kbd><var><b>$this</b></var><kbd>-&gt;</kbd><var><u>exists</u></var><kbd>())
        {
            </kbd><var><b>$this</b></var><kbd>-&gt;</kbd><var><u>get</u></var><kbd>();
        }
        return </kbd><var><b>$this</b></var><kbd>;
    }

}</kbd>
</pre>

<h3>application/models/user.php</h3>
<pre>
<kbd>class </kbd><var>User </var><kbd>extends </kbd><var>DataMapperExt </var><kbd>{
    </kbd><samp>// Standard DataMapper definition
    </samp><kbd>function </kbd><var><dfn>__construct</dfn></var><kbd>(</kbd><var>$id </var><kbd>= </kbd><var>NULL</var><kbd>) {
        </kbd><var><dfn>parent</dfn></var><kbd>::</kbd><var><dfn>__construct</dfn></var><kbd>(</kbd><var>$id</var><kbd>);
    }
    </kbd><samp>// ...
</samp><kbd>}</kbd>
</pre>

<p>Now you can add any methods or properties you want to <var>DataMapperExt</var>, and they will be visible to any model that subclasses <var>DataMapperExt</var>.  You can even overwrite default DataMapper methods.</p>

<p>The drawbacks to this method is that it is very difficult to share this kind of extension, and it isn't very modular.  In any case, I highly recommend it whenever you think you need to edit DataMapper directly.</p>



</div>
<!-- END CONTENT -->


<div id="footer">
<p>
<span id="footer_previous">Previous Topic:&nbsp;&nbsp;<a href=""></a>
&nbsp;&nbsp;&nbsp;&middot;&nbsp;&nbsp;</span>
<a href="#top">Top of Page</a>&nbsp;&nbsp;&nbsp;&middot;&nbsp;&nbsp;
<a href="../index.html">User Guide Home</a>
<span id="footer_next">&nbsp;&nbsp;&nbsp;&middot;&nbsp;&nbsp;
Next Topic:&nbsp;&nbsp;<a href=""></a></span>
</p>
<div id="copyrights">
<p><a href="/">Datamapper ORM</a> &nbsp;&middot;&nbsp; Copyright &copy; 2010-2011 &nbsp;&middot;&nbsp; Harro "WanWizard" Verton</p>
<p><a href="license.html">Other License Information</a></p>
</div>
</div>

<script type="text/javascript" src="../js/mootools.js"></script>
<script type="text/javascript" src="../js/menu.js"></script>
<script type="text/javascript">
<!--
	window.addEvent('domready', function() {

		// Create Menu
		var menu = new Menu({
			basepath: '../',
			pagespath: ''
		});

	});
//-->
</script>
</body>
</html>
